feat: add markdown output support for package pages#151
feat: add markdown output support for package pages#151BYK wants to merge 16 commits intonpmx-dev:mainfrom
Conversation
|
@BYK is attempting to deploy a commit to the danielroe Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
|
ultimately it might make sense to share some logic with the client (see #169) so we can click 'copy as markdown' ...although that button could also fetch the markdown from the server endpoint, which might be better from a JS bundle size so... just linking so you're aware |
|
@atinux @okineadev are you waiting on me for something? (just making sure I'm not the blocker here) |
|
Sorry I was quite busy. I suggest to not use a middleware here but instead having a server route with Then like on https://github.com/unjs/undocs/blob/main/app/modules/md-rewrite.ts, we can add the rewrite in the generated Would you be up to update your PR with this approach @BYK ? |
Add support for getting package information in Markdown format via: - URL suffix: /package-name.md - Accept header: text/markdown Includes security hardening: - URL validation for homepage/bugs links (prevents javascript: injection) - README size limit (500KB) to prevent DoS - Path exclusion alignment between Vercel rewrites and middleware
Address review feedback from @atinux: - Replace middleware with server route at /raw/[...slug].md - Update vercel.json rewrites to point to /raw/:path.md - Add curl user-agent rewrite support for CLI tools - Enable CDN-level caching for markdown responses Also fix maintainer URLs to use npmx.dev instead of npmjs.com
|
@atinux no worries. Updated :) |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds server-side support to serve package information as Markdown via a new /raw/** route and a server route handler that parses slugs, resolves package and version data, fetches README with a jsDelivr fallback, obtains weekly and 12‑week download stats and repository info, and returns generated Markdown with Content-Type text/markdown and ISR-aligned caching (60s). Adds server-side markdown generation utilities (sparkline, formatting, URL normalisation, README handling), an ISR route rule for /raw/** in nuxt.config, a markdown alternate link on the package page, Vercel rewrites for markdown/curl requests, unit tests for markdown utilities, and a codecov ignore update. Suggested reviewers
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (3)
server/routes/raw/[...slug].md.get.ts (1)
130-235: Consider splitting the handler into smaller helpers.This handler is well over the 50-line guideline; extracting readme, downloads, and version resolution into helpers would improve readability and testability.
As per coding guidelines: Keep functions focused and manageable (generally under 50 lines).
server/utils/markdown.ts (2)
8-27: Guard the sparkline index access.Clamping or fallbacking the array access keeps the indexing explicitly safe.
As per coding guidelines: Ensure you write strictly type-safe code, for example by ensuring you always check when accessing an array value by index.🛠️ Safer index access
- const index = Math.round(normalized * (SPARKLINE_CHARS.length - 1)) - return SPARKLINE_CHARS[index] + const index = Math.round(normalized * (SPARKLINE_CHARS.length - 1)) + return SPARKLINE_CHARS[index] ?? SPARKLINE_CHARS[SPARKLINE_CHARS.length - 1]
115-279: Consider extracting sections to reduce function length.
generatePackageMarkdownis very long; splitting into section builders (stats, links, readme) would improve readability and maintenance.As per coding guidelines: Keep functions focused and manageable (generally under 50 lines).
|
@atinux ready for another look? |
|
ah! we do now have a copy as markdown button on the frontend #1020 - if you rebase you could make any change you need to use your new logic? It would be nice if that button also fetched it dynamically |
Co-authored-by: Okinea Dev <hi@okinea.dev>
|
I think we should also take a look at #1382 |
# Conflicts: # app/pages/package/[...package].vue # nuxt.config.ts
…supplied maintainer fields - Add vercel.json rewrites for /package/:path to strip prefix and serve markdown - Escape maintainer name with escapeMarkdown() since it's user-supplied - URL-encode maintainer username in link hrefs for safety
|
Thanks for the pointer to #1382! That PR adds I think it makes sense to keep these as separate PRs that can be coordinated:
They share some underlying infrastructure (markdown generation, package metadata), so once both land, there could be follow-up work to consolidate shared utilities. But merging them now would significantly expand scope. |
|
@okineadev @ghostdevv sorry for the long delay. Should be good to go now? |
Personally, I abstain from voting. |
|
@okineadev who can vote so we can avoid bitrot? :) |
Summary
Add support for getting package information in Markdown format, useful for AI/LLM consumption and command-line tools.
Access Methods
/<package>.md(e.g.,/vue.md,/@nuxt/kit.md)Accept: text/markdownOutput Includes
Security Hardening
javascript:protocol injection)